package org.andy.util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.SecureRandom;

/**
 * UUID类。
 * <p>getUUID() 方法 使用了java自带的UUID生成工具生成UUID。</p>
 * <p>create() 完全拷贝了seasar2框架的生成算法代码。</p>
 *
 * @author andy
 * @version V1.0
 * @date 18/2/5 下午8:47
 */
public class UUIDGenerator {

    /**
     * 获得32位UUID。
     * 通过jdk 的UUID工具类生成uuid。
     *
     * @return
     */
    public static String getUUID() {
        return java.util.UUID.randomUUID()
            .toString().replace("-", "");
    }

    private static final byte[] DEFAULT_ADDRESS = new byte[] { (byte) 127,
        (byte) 0, (byte) 0, (byte) 1 };

    private static SecureRandom _random = new SecureRandom();

    private static String _base = toHex(getAddress())
        + toHex(System.identityHashCode(_random));

    /**
     * UUID创建。
     *
     * @return  String
     */
    public static String create() {
        StringBuffer buf = new StringBuffer(_base.length() * 2);
        buf.append(_base);
        int lowTime = (int) System.currentTimeMillis() >> 32;
        appendHex(buf, lowTime);
        appendHex(buf, _random.nextInt());
        return buf.toString();
    }

    /**
     * 变换成16进数的字符串。
     *
     * @param bytes
     *           字节的排列
     * @return 16位的字符串
     */
    public static String toHex(final byte[] bytes) {
        if (bytes == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; ++i) {
            appendHex(sb, bytes[i]);
        }
        return sb.toString();
    }

    /**
     * 转换成16进数的字符串。
     *
     * @param i int
     * @return String
     */
    public static String toHex(final int i) {
        StringBuffer buf = new StringBuffer();
        appendHex(buf, i);
        return buf.toString();
    }

    /**
     * 把数字序列转换成16进数的字符串。
     * @param buf   附加的字符串
     * @param i 数值
     */
    public static void appendHex(final StringBuffer buf, final byte i) {
        buf.append(Character.forDigit((i & 0xf0) >> 4, 16));
        buf.append(Character.forDigit((i & 0x0f), 16));
    }

    private static byte[] getAddress() {
        try {
            return InetAddress.getLocalHost().getAddress();
        } catch (UnknownHostException ignore) {
            return DEFAULT_ADDRESS;
        }
    }

    /**
     * 把字符串转换成16进数的字符串。
     *
     * @param buf 附加的字符串
     * @param i 数值
     */
    public static void appendHex(final StringBuffer buf, final int i) {
        buf.append(Integer.toHexString((i >> 24) & 0xff));
        buf.append(Integer.toHexString((i >> 16) & 0xff));
        buf.append(Integer.toHexString((i >> 8) & 0xff));
        buf.append(Integer.toHexString(i & 0xff));
    }

}
